with ada.text_io;
package body v_string is

    package t_io renames ada.text_io;

    null_buf : constant vbuffer := (others => ' ');

    procedure vget ( item : out vstring ) is
	c : Character;
	EOL : Boolean;
    begin
	loop
	    t_io.look_ahead(c, EOL);
	    exit when c /= ' ';
	    if EOL then
		raise EOL_error;
	    end if;
	    t_io.get(c);
	end loop;
	for i in vrange loop
	    t_io.get(c);
	    exit when c = ' ';
	    item.buf(i) := c;
	    item.len := i;
	    exit when t_io.end_of_line;
	end loop;
	if item.len = 0 then
	    item.is_null := true;
	else
	    item.is_null := false;
	end if;
    end vget;

    procedure vget_line ( item : out vstring ) is
    begin
	if t_io.end_of_line = true then
	    raise EOL_error;
	end if;
	t_io.get_line(item.buf, item.len);
	if item.len = 0 then
	    item.is_null := true;
	else
	    item.is_null := false;
	end if;
    end vget_line;

    procedure vput ( item : in vstring ) is
    begin
	t_io.put(item.buf(1..item.len));
    end vput;

    function vgetToken ( item : vstring; tok : Integer ) return vstring is
	index, i, count : natural;
	token : vstring;
    begin
	index := 0;
	count := 1;
	loop
	    index := index + 1;
	    exit when item.buf(index) /= ' ';
	end loop;
	loop
	    if item.buf(index) = ' ' or index = item.len then
		count := count + 1;
	    end if;
	    if count = tok then
		exit;
	    end if;
	    index := index + 1;
	end loop;
	if count /= tok then
	    raise token_not_found;
	end if;
	loop
	    exit when item.buf(index) /= ' ';
	    index := index + 1;
	end loop;
	i := 1;
	loop
	    token.buf(i) := item.buf(index);
	    i := i + 1;
	    index := index + 1;
	    exit when item.buf(index) = ' ' or index = item.len + 1;
	end loop;
	token.len := i-1;
	token.is_null := false;
	return token;
    end vgetToken;

    procedure vput_line ( item : in vstring ) is
    begin
	t_io.put_line(item.buf(1..item.len));
    end vput_line;

    function toVstring ( item : in String ) return vstring is
	v : vstring;
    begin
	if item'last > max then
	    v.len := max;
	else
	    v.len := item'last;
	end if;
	for i in 1..v.len loop
	    v.buf(i) := item(i);
	end loop;
	return v;
    end toVstring;

    function vlength ( item : vstring ) return vrange is 
    begin
	return item.len;
    end vlength;
    
    function vcompare (vstr1 : vstring; vstr2 : vstring) return Boolean is
    begin
	if vstr1.len /= vstr2.len then
	    return false;
	end if;
	for i in 1..vstr1.len loop
	    if vstr1.buf(i) /= vstr2.buf(i) then
		return false;
	    end if;
	end loop;
	return true;
    end vcompare;

    function vcompare (vstr1 : vstring; str : string) return Boolean is
    begin
	return vcompare(vstr1, toVstring(str));
    end vcompare;

    function v_null return vstring is
    begin
	return vstring'(null_buf, 1, true);
    end v_null;

end v_string;
